package com.olda.play.auth.security.config.oauth2;

import com.olda.play.auth.security.token.JwtAccessToken;
import com.olda.play.auth.security.userdetails.client.ClientDetailsServiceImpl;
import com.olda.play.redis.RedisUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;

import java.security.KeyPair;

/**
 * 认证授权配置
 * todo AuthorizationConfig 这个配置类是整个认证服务实现的核心。总结下来就是两个关键点，客户端信息配置和access_token生成配置。
 */

/**
 * todo 如何获取oauth2-token?--------通过TokenEndpoint暴露/oauth/token接口获取toke。
 * TokenEndpoint的注入---@EnableAuthorizationServer【开启授权服务】---
 *      开启授权时，会在 AuthorizationServerEndpointsConfiguration 中找到TokenEndpoint的初始化。
 */
@EnableAuthorizationServer
@Configuration
@RequiredArgsConstructor
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {

    private final ClientDetailsServiceImpl clientDetailsService;
    private final AuthenticationManager authenticationManager;
    private final RedisUtil redisUtil;


    /**
     * 配置OAuth2客户端
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(clientDetailsService);
    }

    /**
     * 配置授权（authorization）以及令牌（token）的访问端点和令牌服务(token services)
     * @param endpoints
     * @throws Exception
     */
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints
                .authenticationManager(authenticationManager)
                // 配置JwtAccessToken转换器
                .accessTokenConverter(jwtAccessTokenConverter());
    }


    /**
     * 使用非对称加密算法来对Token进行签名
     * @return
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {

        final JwtAccessTokenConverter converter = new JwtAccessToken();
        // 导入证书
        KeyStoreKeyFactory keyStoreKeyFactory =
                new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "123456".toCharArray());
        KeyPair keyPair = keyStoreKeyFactory.getKeyPair("jwt", "123456".toCharArray());
        converter.setKeyPair(keyPair);
        return converter;
    }







}
